import compiler

import _visitor

__version__ = "0.1"

class Epy:
    """
        Contains interface methods and "global" blocklevel (for indentation) as
        well as the "global" namespace (a stack where each layer is a list of
        strings containing the labels at that level) that gets pushed and popped
        as the parser enters/exits namespaces.
    """
    def __init__(self):
        self.blocklevel = 0
        self.namespace = [[]]
        self.used = []
        self.src = ""
        self.modules = []
        self.isModule = False

    def error(self, error, line):
        return "[Epy: ERROR] %s, line: %s" % (error, str(line))

    def warn(self, warning, line):
        print "[Epy: WARNING] %s, line: %s" % (warning, str(line))

    def indent(self):
        return "".join(["    " for i in xrange(self.blocklevel)])

    def pushLevel(self):
        self.blocklevel += 1

    def popLevel(self):
        self.blocklevel -= 1

    def pushNS(self):
        self.namespace.append([])

    def popNS(self):
        self.namespace.pop()

    def isDeclared(self, name):
        for ns in self.namespace:
            if name in ns:
                return True
        return False

    def addVar(self, name):
        self.namespace[-1].append(name)

    def parseNode(self, node):
        myvisitor = _visitor.EPYVisitor(self)
        return compiler.walk(node, myvisitor).src

    def compileModule(self, moduleName, infile, outfile):
        self.isModule = True
        self.src = ""
        self.src += "function epy_module_%s() {\n" % moduleName
        self.pushLevel()
        self.src += "%svar epy_module = new Object();\n" % self.indent()
        self.src += self.parseNode(compiler.parseFile(infile).node)
        self.src += "%sreturn epy_module;\n" % self.indent()
        self.popLevel()
        self.src += "}\n"
        open(outfile, "w").write(self.toString())

    def compileMain(self, infile, outfile):
        self.src = ""
        self.src += "window.onload = function() {\n"
        self.pushLevel()
        self.src += self.parseNode(compiler.parseFile(infile).node)
        self.popLevel()
        self.src += "}\n"

        imports = ""
        for module in ["epy"] + self.modules:
            imports += """<script type="text/javascript" src="./%s.js"></script>\n""" % module
        open(outfile, "w").write("""<html>
<head>
%s<script type="text/javascript">
%s</script>
</head>
<body>
</body>
</html>""" % (imports, self.toString()))

    def toString(self):
        return "/*\n    JavaScript generated by Epy v%s\n*/\n%s" % (__version__, self.src)
